package com.yc.thread;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.Random;
import java.util.concurrent.*;

/**
 * 线程死锁测试
 * @author yc112
 */
public class ThreadTest {

    private static Object resource1 = new Object();//资源 1

    private static Object resource2 = new Object();//资源 2

    private static Object resource3 = new Object();//资源 3

    public static void main(String[] args) {
        int a = 100;
        Integer b = new Integer(100);
        Integer c = 100;

        System.out.println(a == b); // true
        System.out.println(a == c); // true
        System.out.println(b == c); // false
//        ThreadTest tt = new ThreadTest();
//        tt.testThreadPoolFinished();
//        tt.testThreadPoolFinished2();
    }

    /**
     * 测试线程池代码执行完成
     */
    public void testThreadPoolFinished() {

        // 方式1 通过pool.getTaskCount() 和 pool.getCompletedTaskCount() 对比来判断执行情况
        ThreadPoolExecutor pool = new ThreadPoolExecutor(10, 10,
                0L, TimeUnit.SECONDS, new LinkedBlockingDeque<Runnable>());

        for(int i=0;i<10;i++){
            pool.submit(new Runnable() {
                public void run() {
                    System.out.println("当前线程:"+Thread.currentThread().getName()+",打印随机数:"+ new Random().nextInt(1000));
                }
            });
        }
        System.out.println("pool.getTaskCount():"+pool.getTaskCount());
        System.out.println("pool.getCompletedTaskCount():"+pool.getCompletedTaskCount());
        boolean allThreadsIsDone = pool.getTaskCount() == pool.getCompletedTaskCount();
        System.out.println(allThreadsIsDone);
        if(allThreadsIsDone){
            System.out.println("全部执行完成");
        }
        while (!allThreadsIsDone){
            allThreadsIsDone = pool.getTaskCount()==pool.getCompletedTaskCount();
            if(allThreadsIsDone){
                System.out.println("全部执行完成");
            }
        }



    }

    // 第二种方式 ，先执行exec.shutdown(); 然后写一个while(true)循环判断exec.isTerminated()
    // 还有使用CountDownLatch方式来判断
    public void testThreadPoolFinished2() {
//        final File stream = new File("c:\\temp\\stonefeng\\stream.txt");
//        final OutputStream os = new FileOutputStream(stream);
//        final OutputStreamWriter writer = new OutputStreamWriter(os);
//        final Semaphore semaphore = new Semaphore(10);
//        ExecutorService exec = Executors.newCachedThreadPool();
        ThreadPoolExecutor exec = new ThreadPoolExecutor(10, 10,
                0L, TimeUnit.SECONDS, new LinkedBlockingDeque<Runnable>());
        final long start = System.currentTimeMillis();
        for (int i = 0; i < 10; i++) {
            final int num = i;
            Runnable task = new Runnable() {
                @Override
                public void run() {
                    System.out.println("当前线程:"+Thread.currentThread().getName()+",打印随机数:"+ new Random().nextInt(1000));
//                    try {
//                        semaphore.acquire();
//                        writer.write(String.valueOf(num)+"\n");
//                        semaphore.release();
//                    } catch (IOException e) {
//                        e.printStackTrace();
//                    } catch (InterruptedException e) {
//                        e.printStackTrace();
//                    }
                }
            };
            exec.submit(task);
        }
        exec.shutdown();
        while(true){
            if(exec.isTerminated()){
//                writer.write("---END---\n");
//                writer.close();
                System.out.println("所有的子线程都结束了！");
                break;
            }
//            Thread.sleep(1000);
        }
        final long end = System.currentTimeMillis();
        System.out.println((end-start)/1000);
    }


    /**
     * 测试死锁。
     * 线程1 锁住了资源2一直没释放
     * 线程2 需要资源2的锁，但一直没获取到
     */
    public void testDeadLock() {
        new Thread(() -> {
            synchronized (resource1) {
                System.out.println(Thread.currentThread() + "get resource1");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread() + "waiting get resource2");
                synchronized (resource2) {
                    System.out.println(Thread.currentThread() + "get resource2");
                }
            }
        }, "线程 1").start();

        new Thread(() -> {
            synchronized (resource2) {
                System.out.println(Thread.currentThread() + "get resource2");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread() + "waiting get resource1");
                synchronized (resource1) {
                    System.out.println(Thread.currentThread() + "get resource1");
                }
            }
        }, "线程 2").start();

//        new Thread(() -> {
//            synchronized (resource3) {
//                System.out.println(Thread.currentThread() + "get resource3");
//            }
//            try {
//                Thread.sleep(1000);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//            System.out.println(Thread.currentThread() + "waiting get resouce3");
//            synchronized (resource1) {
//                System.out.println(Thread.currentThread() + "get resource1");
//            }
//        }, "线程 3").start();
    }
}
